Note
Go to the end to download the full example code.
Custom logging setup using python built-in logging functionality.
# pylint: disable=invalid-name
import logging
import logging.config # allows to specify advanced custom configurations
import QuantumIsing_1d_quench as example
def simple_logging_config():
"""
Simple logging configuration via `logging.basicConfig`
https://docs.python.org/3/library/logging.html#logging.basicConfig
"""
logging.basicConfig(
# tweak output format
format="%(asctime)s [%(name)s:%(levelname)s] %(message)s",
# ------
# log severity INFO or higher
level="INFO",
# note: qtealeaves' default is to log
# >= INFO for qtealeaves.simulation
# >= WARNING for other modules
# ------
# uncomment next line to log to file
# filename="log_file_path.log",
)
def advanced_logging_config():
"""
Advanced logging configuration via `logging.config.dictConfig`
https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig
https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema
see also `logging.config.fileConfig`
https://docs.python.org/3/library/logging.config.html#logging.config.fileConfig
https://docs.python.org/3/library/logging.config.html#configuration-file-format
"""
# A (fairly advanced) way of specifying custom logging setups
# is through a dictionary (possibly stored in yaml/json)
logging_config = {
# schema version, only valid value at present is 1
"version": 1,
# if True (default), non-root loggers have to be listed
# in "loggers" below in order to be active
"disable_existing_loggers": False, # default is True
# configuration for the root logger, from which all loggers inherit
"root": {
# https://docs.python.org/3/library/logging.html#levels
"level": "WARNING", # python's default for root logger log
"handlers": ["console", "file"], # handlers defined below
},
# sub-loggers, inherit their configuration from the parent loggers
# (e.g. X.Y inherits from X which inherits from the root logger)
# but can integrate it with custom: level, propagate, filters, handlers
"loggers": {
# must mention explicitly if disable_existing_loggers is True
"qtealeaves": {},
# reproduce qtealeaves' default
"qtealeaves.simulation": {"level": "INFO"},
# if we are interested in the details of the emulator
"qtealeaves.emulator": {"level": "DEBUG"},
},
# logging destinations (can even be a network socket or email server)
# https://docs.python.org/3/library/logging.handlers.html
# can specify custom: level, formatter, filters
"handlers": {
"file": {
"class": "logging.FileHandler",
"filename": "sim.log",
"mode": "w",
# handler-specific formatter, among those defined below
"formatter": "detailed",
},
"console": {
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout",
"formatter": "detailed",
# handler-specific level, DEBUG won't go to STDOUT
"level": "INFO",
},
},
# logging output formatting (can define many, for different handlers)
# https://docs.python.org/3/library/logging.html#logging.Formatter
"formatters": {
# only messages whose severity INFO or higher
"detailed": {
"format": "%(asctime)s %(levelname)-8s | %(message)s",
"datefmt": "%Y-%m-%d %H:%M",
}
},
}
logging.config.dictConfig(logging_config)
if __name__ == "__main__":
logger = logging.getLogger("example-script")
# qtealeaves configures logging automatically,
# setting the level of loggers in qtealeaves.simulation to INFO
# (set `has_log_file=True` in the example to log to file as well)
# to tweak a bit the output, uncomment to see effect
# simple_logging_config()
# advanced configuration via dictionary, uncomment to see effect
# advanced_logging_config()
# run an example with the customized logging
example.main()